#include <stdio.h>
#include <stdlib.h>

struct LIST
{
    int a, b;
} d[3], *p;

// 返回结构值
struct LIST make1(int x, int y)
{
    struct LIST temp;
    temp.a = x;
    temp.b = y;
    return temp;
}

// 返回结构指针
struct LIST *make2(int x, int y)
{
    struct LIST *temp;
    temp = (struct LIST *)malloc(sizeof(struct LIST));
    temp->a = x;
    temp->b = y;
    return temp;
}

int main()
{
    int i;
    d[0] = make1(25, 52);
    p = make2(85, 58);
    d[1] = *p;
    d[2] = d[0]; // 结构可以整体赋值
    for (i = 0; i < 3; i++)
        printf("d[%d].a=%d,d[%d].b=%d\n",
               i, d[i].a, i, d[i].b);
    system("pause");
    return 0;
}

/*

设计一个函数并不难，难的是设计合理的函数类型及参数传递方式，并能正确地使用它们。
    函数类型决定函数返回值的类型，
    而参数传递既要考虑哪些可以作为函数参数，也要考虑是否允许改变这些参数。

函数就是一段封装起来的有名字的程序代码，
这种封装把函数的里面和外面分开，形成函数的内部和外部。
    从外部看，使用者关心的应是函数实现的功能，而不是函数功能的实现。
    程序员只需知道函数的名字和特征，遵守调用规则，提供规定数量的、类型适当的实参并正确接收返回值，即可得到预期的运行结果。
    例如，虽然不知道标准库函数如何实现，但并不影响人们正确使用它们。

    从内部看，设计者不需要去关心程序的哪里将调用这个函数及如何提供具体的实参值，
    而应该关心函数被调用时，外部将提供哪些数据及其类型（也就是参数表）；
    如何利用参数进行计算（算法）；
    函数如何结束及函数如何产生返回值等问题。

函数类型说明 函数名（形式参数列表）

设计函数时，需要正确设计函数类型、函数参数传递方式和返回值。
    1）C语言函数参数的传递方式只有传值一种。
    2）参数传递中不要混淆传地址值和传地址。
        C语言没有传递地址的方式，它传地址值时，传递的是值不是地址，传递变量地址值是使用变量指针作为参数。
        C++语言有传地址方式，C++语言传地址方式传的是地址不是地址值，传递地址时使用变量引用作为参数。
    3）不要混淆变量和传递参数。
        设计函数需要考虑的是传递参数要达到哪种目的。
            如果要改变的是传递参数的值，则要传递地址值。
            如果改变的是其他变量的值，则不一定要传递参数的地址值。
    4）返回值必须与函数类型相一致。
        从返回值的角度看，函数的返回值类型可以是除数组和函数以外的任何类型。
            定义一个函数，要正确选择函数返回值。
            非void类型的函数必须向调用者返回一个值。
        该值可以是标量变量，也可以是复合变量。
            标量变量指那些声明为基本类型的变量，此类返回值置于寄存器中。在函数中，数值作为特殊情况处理。
                除非使用静态数组，否则数组只是临时数组，离开函数即不复存在，而且静态数组也只能返回地址值。
            复合变量是指结构等构造类型的变量，这种复合变量比较特殊，对于结构而言，既可以返回结构变量，也可以返回结构指针。
                返回结构需要对结构的域值逐个进行复制，如果结构很大，则效率较低。
                通常使用结构变量的指针来传递结构变量的地址值


*/